package com.uinnova.product.eam.service.impl;

import com.binary.core.util.BinaryUtils;
import com.binary.framework.exception.ServiceException;
import com.uinnova.product.eam.base.exception.ServerException;
import com.uinnova.product.eam.comm.model.es.EamDiagramRelationSys;
import com.uinnova.product.eam.comm.utils.CiUtil;
import com.uinnova.product.eam.model.EamDiagramRelationSysCdt;
import com.uinnova.product.eam.service.EamDiagramRelationSysService;
import com.uinnova.product.eam.service.ICISwitchSvc;
import com.uinnova.product.eam.service.IEamDiagramSvc;
import com.uinnova.product.eam.service.es.EamDiagramRelationSysDao;
import com.uinnova.product.vmdb.provider.ci.bean.CcCiInfo;
import com.uinnova.product.vmdb.provider.ci.bean.CiGroupPage;
import com.uinnova.product.vmdb.provider.search.bean.CcCiClassObj;
import com.uinnova.product.vmdb.provider.search.bean.CcCiObj;
import com.uinnova.product.vmdb.provider.search.bean.CcCiSearchPage;
import com.uinnova.project.base.diagram.comm.model.ESDiagram;
import com.uino.bean.cmdb.base.LibType;
import com.uino.bean.cmdb.query.ESCISearchBean;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description: 制品关联系统
 * @author: Lc
 * @create: 2022-01-19 21:00
 */
@Service
public class EamDiagramRelationSysServiceImpl implements EamDiagramRelationSysService {


    private static Random random = new Random();

    @Resource
    private EamDiagramRelationSysDao eamDiagramRelationSysDao;

    @Resource
    private ICISwitchSvc ciSwitchSvc;

    @Resource
    private IEamDiagramSvc eamDiagramSvc;

    @Override
    public boolean saveDiagramRelationSys(EamDiagramRelationSysCdt eamDiagramRelationSysCdt) {
        if (eamDiagramRelationSysCdt == null) {
            throw new ServerException("参数不能为空!");
        }
        if (StringUtils.isEmpty(eamDiagramRelationSysCdt.getDiagramEnergy())) {
            throw new ServiceException("视图信息不能为空!");
        }
        if (eamDiagramRelationSysCdt.getDirId() == null) {
            throw new ServiceException("文件夹主键不能为空!");
        }
        if (eamDiagramRelationSysCdt.getEsSysId() == null) {
            throw new ServiceException("所属系统不能为空!");
        }
        EamDiagramRelationSys relationSys = new EamDiagramRelationSys();
        BeanUtils.copyProperties(eamDiagramRelationSysCdt, relationSys);
        relationSys.setDelFlag(false);
        eamDiagramRelationSysDao.saveOrUpdate(relationSys);
        return true;
    }

    /**
     * 批量新增视图关联系统
     *
     * @param list {@link EamDiagramRelationSysCdt}
     */
    @Override
    public void saveDiagramRelationSys(List<EamDiagramRelationSysCdt> list) {
        if (BinaryUtils.isEmpty(list)) {
            return;
        }

        list.removeIf(this::checkParam);

        if (BinaryUtils.isEmpty(list)) {
            return;
        }

        eamDiagramRelationSysDao.saveOrUpdateBatch(list.stream().map(cdt -> {
            EamDiagramRelationSys relationSys = new EamDiagramRelationSys();
            BeanUtils.copyProperties(cdt, relationSys);
            relationSys.setDelFlag(false);
            return relationSys;
        }).collect(Collectors.toList()));
    }

    private boolean checkParam(EamDiagramRelationSysCdt cdt) {
        return cdt == null || StringUtils.isBlank(cdt.getDiagramEnergy()) || cdt.getDirId() == null || cdt.getEsSysId() == null;
    }

    @Override
    public EamDiagramRelationSys getEamDiagramRelationSys(String diagramEnergy) {
        if (StringUtils.isEmpty(diagramEnergy)) {
            throw new ServiceException("视图信息不能为空!");
        }
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(QueryBuilders.termQuery("diagramEnergy.keyword", diagramEnergy));
        List<EamDiagramRelationSys> list = eamDiagramRelationSysDao.getListByQuery(queryBuilder);
        if (!CollectionUtils.isEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 批量查询视图关联系统信息
     *
     * @param diagramEnergy 视图加密Id
     * @return {@link EamDiagramRelationSys}
     */
    @Override
    public List<EamDiagramRelationSys> getEamDiagramRelationSys(Collection<String> diagramEnergy) {
        return getEamDiagramRelationSys(diagramEnergy, Boolean.FALSE);
    }

    /**
     * 批量查询视图关联系统信息
     *
     * @param diagramEnergy 视图加密Id
     * @param delFlag       删除标识
     * @return {@link EamDiagramRelationSys}
     */
    @Override
    public List<EamDiagramRelationSys> getEamDiagramRelationSys(Collection<String> diagramEnergy, Boolean delFlag) {
        if (BinaryUtils.isEmpty(diagramEnergy)) {
            return Collections.emptyList();
        }
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(QueryBuilders.termsQuery("diagramEnergy.keyword", diagramEnergy));
        if (delFlag != null) {
            queryBuilder.must(QueryBuilders.termQuery("delFlag", delFlag));
        }
        List<EamDiagramRelationSys> list = eamDiagramRelationSysDao.getListByQuery(queryBuilder);

        return BinaryUtils.isEmpty(list) ? Collections.emptyList() : list;
    }

    /**
     * 给{@link ESDiagram}对象的系统相关字段赋值
     *
     * @param esDiagramList {@link ESDiagram}
     */
    @Override
    public void esDiagramSetRelationProperties(List<ESDiagram> esDiagramList) {
        List<String> diagramEnergyList = esDiagramList.stream().map(ESDiagram::getDEnergy).collect(Collectors.toList());
        List<EamDiagramRelationSys> relationList = getEamDiagramRelationSys(diagramEnergyList);

        Map<String, EamDiagramRelationSys> map = getRelationMap(relationList);
        if (map == null || map.size() == 0) {
            return;
        }

        CcCiSearchPage ccCiSearchPage = getCcCiSearchPage(relationList);
        Map<String, CcCiObj> ciMap = ccCiSearchPage.getTotalRows() == 0 ? Collections.emptyMap() :
                getCiCodeAndClassMap(ccCiSearchPage);

        Map<Long, CcCiClassObj> classMap = ccCiSearchPage.getData().getClassMp();

        for (ESDiagram esDiagram : esDiagramList) {
            String dEnergy = esDiagram.getDEnergy();
            EamDiagramRelationSys relation = map.get(dEnergy);
            if (relation != null) {
                String ciCode = relation.getEsSysId();
                CcCiObj ccCiObj = ciMap.get(ciCode);
                if (ccCiObj == null) {
                    continue;
                }
                String sysName = CiUtil.parseCiLabel(ccCiObj.getCi());
                Long classId = ccCiObj.getCi().getClassId();
                CcCiClassObj ccCiClassObj = classMap.get(classId);
                String className = ccCiClassObj.getCls().getClassName();

                esDiagram.setCiCode(ciCode);
                esDiagram.setRelationSystem(sysName);
                esDiagram.setSystemType(className);
            }
        }
    }

    @Override
    public List<EamDiagramRelationSys> findDiagramRelationSysList(String esSysId) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(QueryBuilders.termQuery("esSysId.keyword", esSysId));
        queryBuilder.must(QueryBuilders.termQuery("delFlag", false));
        return eamDiagramRelationSysDao.getListByQuery(queryBuilder);
    }

    @Override
    public List<EamDiagramRelationSys> updateDiagramRelationSys(Long dirId) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(QueryBuilders.termQuery("dirId", dirId));
        queryBuilder.must(QueryBuilders.termQuery("delFlag", false));
        List<EamDiagramRelationSys> relationSysList = eamDiagramRelationSysDao.getListByQuery(queryBuilder);
        CiGroupPage ciGroupPage = eamDiagramSvc.findDesignCiSysList();
        List<CcCiInfo> ciInfoList = ciGroupPage.getData();
        List<CcCiInfo> newCiInfoList = new ArrayList<>();
        for (EamDiagramRelationSys eamDiagramRelationSys : relationSysList) {
            if (newCiInfoList.size() == 599) {
                System.out.println("123");
            }
            ciInfoList.removeAll(newCiInfoList);
            if (org.springframework.util.CollectionUtils.isEmpty(ciInfoList)) {
                ciInfoList = new ArrayList<>(newCiInfoList);
                newCiInfoList.clear();
            }

            int i = 0;
            if (ciInfoList.size() != 1) {
                i = random.nextInt(ciInfoList.size());
            } else {
                i = 0;
            }
            CcCiInfo ciInfo = ciInfoList.get(i);
            newCiInfoList.add(ciInfo);
            eamDiagramRelationSys.setEsSysId(ciInfo.getCi().getCiCode());
        }
        eamDiagramRelationSysDao.saveOrUpdateBatch(relationSysList);
        return relationSysList;
    }

    private CcCiSearchPage getCcCiSearchPage(List<EamDiagramRelationSys> relationList) {
        List<String> ciCodeList =
                relationList.stream().map(EamDiagramRelationSys::getEsSysId).collect(Collectors.toList());

        ESCISearchBean bean = new ESCISearchBean();
        bean.setPageSize(3000);
        bean.setCiCodes(ciCodeList);
        return ciSwitchSvc.searchCIByBean(bean, LibType.DESIGN);
    }

    private Map<String, EamDiagramRelationSys> getRelationMap(List<EamDiagramRelationSys> relationList) {
        if (BinaryUtils.isEmpty(relationList)) {
            return null;
        }

        // key: 视图加密Id value:关系
        return relationList.stream().collect(Collectors.toMap(EamDiagramRelationSys::getDiagramEnergy,
                s -> s, (k1, k2) -> k1));
    }

    private Map<String, CcCiObj> getCiCodeAndClassMap(CcCiSearchPage ccCiSearchPage) {
        List<CcCiObj> ciList = ccCiSearchPage.getData().getRecords();
        return ciList.stream().collect(Collectors.toMap(ccCiObj -> ccCiObj.getCi().getCiCode(),
                ccCiObj -> ccCiObj, (x, y) -> x));
    }

    @Override
    public List<EamDiagramRelationSys> findDiagramByRelationSysList(List<String> esSysIds) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(QueryBuilders.termsQuery("esSysId.keyword", esSysIds));
        queryBuilder.must(QueryBuilders.termQuery("delFlag", false));
        return eamDiagramRelationSysDao.getListByQuery(queryBuilder);
    }
}
